{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Introduction\n",
    "\n",
    "The `Lines` object provides the following features:\n",
    "\n",
    "1. Ability to plot a single set or multiple sets of y-values as a function of a set or multiple sets of x-values\n",
    "2. Ability to style the line object in different ways, by setting different attributes such as the `colors`, `line_style`, `stroke_width` etc.\n",
    "3. Ability to specify a marker at each point passed to the line. The marker can be a shape which is at the data points between which the line is interpolated and can be set through the `markers` attribute"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `Lines` object has the following attributes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " | Attribute |  Description | Default Value  |\n",
    "|:-:|---|:-:|\n",
    "|  `colors` | Sets the color of each line, takes as input a list of any RGB, HEX, or HTML color name  | `CATEGORY10`  |\n",
    "| `opacities`  | Controls the opacity of each line, takes as input a real number between 0 and 1  | `1.0`  |\n",
    "| `stroke_width`  | Real number which sets the width of all paths  | `2.0`  |\n",
    "| `line_style`  | Specifies whether a line is solid, dashed, dotted or both dashed and dotted  | `'solid'`  |\n",
    "| `interpolation`  | Sets the type of interpolation between two points  | `'linear'`  |\n",
    "| `marker`  | Specifies the shape of the marker inserted at each data point  | `None`  |\n",
    "| `marker_size`  | Controls the size of the marker, takes as input a non-negative integer  | `64`  |\n",
    "|`close_path`| Controls whether to close the paths or not | `False` |\n",
    "|`fill`| Specifies in which way the paths are filled. Can be set to one of `{'none', 'bottom', 'top', 'inside'}`| `None` |\n",
    "|`fill_colors`| `List` that specifies the `fill` colors of each path | `[]` |                                                                         \n",
    "| **Data Attribute** |  **Description** | **Default Value**  |\n",
    "|`x` |abscissas of the data points | `array([])` |\n",
    "|`y` |ordinates of the data points | `array([])` |\n",
    "|`color` | Data according to which the `Lines` will be colored. Setting it to `None` defaults the choice of colors to the `colors` attribute | `None` |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## pyplot's plot method can be used to plot lines with meaningful defaults"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from pandas import date_range\n",
    "import bqplot.pyplot as plt\n",
    "from bqplot import ColorScale"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "security_1 = np.cumsum(np.random.randn(150)) + 100.\n",
    "security_2 = np.cumsum(np.random.randn(150)) + 100."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic Line Chart"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(title='Security 1')\n",
    "axes_options = {'x': {'label': 'Index'}, 'y': {'label': 'Price'}}\n",
    "# x values default to range of values when not specified\n",
    "line = plt.plot(security_1, axes_options=axes_options)\n",
    "fig"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**We can explore the different attributes by changing each of them for the plot above:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line.colors = ['DarkOrange']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In a similar way, we can also change any attribute after the plot has been displayed to change the plot. Run each of the cells below, and try changing the attributes to explore the different features and how they affect the plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The opacity allows us to display the Line while featuring other Marks that may be on the Figure\n",
    "line.opacities = [.5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line.stroke_width = 2.5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To switch to an area chart, set the `fill` attribute, and control the look with `fill_opacities` and `fill_colors`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line.fill = 'bottom'\n",
    "line.fill_opacities = [0.2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line.line_style = 'dashed'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line.interpolation = 'basis'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While a `Lines` plot allows the user to extract the general shape of the data being plotted, there may be a need to visualize discrete data points along with this shape. This is where the `markers` attribute comes in."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line.marker = 'triangle-down'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `marker` attributes accepts the values `square`, `circle`, `cross`, `diamond`, `square`, `triangle-down`, `triangle-up`, `arrow`, `rectangle`, `ellipse`. Try changing the string above and re-running the cell to see how each `marker` type looks."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Plotting a Time-Series"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `DateScale` allows us to plot time series as a `Lines` plot conveniently with most `date` formats."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Here we define the dates we would like to use\n",
    "dates = date_range(start='01-01-2007', periods=150)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(title='Time Series')\n",
    "axes_options = {'x': {'label': 'Date'}, 'y': {'label': 'Security 1'}}\n",
    "time_series = plt.plot(dates, security_1, \n",
    "                       axes_options=axes_options)\n",
    "fig"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting multiples sets of data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `Lines` mark allows the user to plot multiple `y`-values for a single `x`-value. This can be done by passing an `ndarray` or a list of the different `y`-values as the y-attribute of the `Lines` as shown below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dates_new = date_range(start='06-01-2007', periods=150)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We pass each data set as an element of a `list`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure()\n",
    "axes_options = {'x': {'label': 'Date'}, 'y': {'label': 'Price'}}\n",
    "line = plt.plot(dates, [security_1, security_2], \n",
    "                labels=['Security 1', 'Security 2'],\n",
    "                axes_options=axes_options,\n",
    "                display_legend=True)\n",
    "fig"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similarly, we can also pass multiple `x`-values for multiple sets of `y`-values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line.x, line.y = [dates, dates_new], [security_1, security_2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Coloring Lines according to data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `color` attribute of a `Lines` mark can also be used to encode one more dimension of data. Suppose we have a portfolio of securities and we would like to color them based on whether we have bought or sold them. We can use the `color` attribute to encode this information."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure()\n",
    "axes_options = {'x': {'label': 'Date'}, \n",
    "                'y': {'label': 'Security 1'},\n",
    "                'color' : {'visible': False}}\n",
    "# add a custom color scale to color the lines\n",
    "plt.scales(scales={'color': ColorScale(colors=['Red', 'Green'])})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dates_color = date_range(start='06-01-2007', periods=150)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "securities = 100. + np.cumsum(np.random.randn(150, 10), axis=0)\n",
    "# we generate 10 random price series and 10 random positions\n",
    "positions = np.random.randint(0, 2, size=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# We pass the color scale and the color data to the plot method\n",
    "line = plt.plot(dates_color, securities.T, color=positions, \n",
    "                axes_options=axes_options)\n",
    "fig"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also reset the colors of the Line to their defaults by setting the `color` attribute to `None`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "line.color = None"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Patches"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `fill` attribute of the `Lines` mark allows us to fill a path in different ways, while the `fill_colors` attribute lets us control the color of the `fill`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig = plt.figure(animation_duration=1000)\n",
    "patch = plt.plot([],[],\n",
    "                 fill_colors=['orange', 'blue', 'red'],\n",
    "                 fill='inside',\n",
    "                 axes_options={'x': {'visible': False}, 'y': {'visible': False}},\n",
    "                 stroke_width=10,\n",
    "                 close_path=True,\n",
    "                 display_legend=True)\n",
    "\n",
    "patch.x = [[0, 2, 1.2, np.nan, np.nan, np.nan, np.nan], [0.5, 2.5, 1.7 , np.nan, np.nan, np.nan, np.nan], [4, 5, 6, 6, 5, 4, 3]], \n",
    "patch.y = [[0, 0, 1  , np.nan, np.nan, np.nan, np.nan], [0.5, 0.5, -0.5, np.nan, np.nan, np.nan, np.nan], [1, 1.1, 1.2, 2.3, 2.2, 2.7, 1.0]]\n",
    "fig"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "patch.opacities = [0.1, 0.2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "patch.x = [[2, 3, 3.2, np.nan, np.nan, np.nan, np.nan], [0.5, 2.5, 1.7, np.nan, np.nan, np.nan, np.nan], [4,5,6, 6, 5, 4, 3]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "patch.close_path = False"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
